home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / source / tsm23s.lha / SaveHAMetc.c < prev    next >
C/C++ Source or Header  |  1993-10-08  |  17KB  |  844 lines

  1. // TSMorph - Amiga Morphing program
  2. // Copyright (C) © 1993  Topicsave Limited
  3.  
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // any later version.
  8.  
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13.  
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. // mpaddock@cix.compulink.co.uk
  19.  
  20. //    $Author: M_J_Paddock $
  21. //    $Date: 1992/08/08 01:10:03 $
  22. //    $Revision: 1.1 $
  23.  
  24. // This is routines to save chunky 24 bit RGB in various formats
  25. // B&W 16 grey scale
  26. // B&W 256 grey scale
  27. // HAM6 with fixed palette (but could easily used variable palette)
  28. // HAM6 with fixed palette (but could easily used variable palette)
  29. // DCTV
  30.  
  31. // include headers
  32. #include <proto/iffparse.h>
  33. #include <graphics/view.h>
  34. #include <libraries/dctv.h>
  35. #include <clib/dctv_protos.h>
  36. #include <pragmas/dctv_pragmas.h>
  37. extern struct Library *DCTVBase;
  38.  
  39. // IFF header
  40. #include "iffp/ILBMapp.h"
  41.  
  42. // Following explains(?) the palette choices
  43.  
  44. //   0 = x00 = b00000000
  45. //  85 = x55 = b01010101
  46. // 170 = xaa = b10101010
  47. // 255 = xff = b11111111
  48.  
  49. //   0 = x00 = o000 = b00000000
  50. //  36 = x24 = o111 = b00100100
  51. //  73 = x49 = o222 = b01001001
  52. // 109 = x6d = o333 = b01101101
  53. // 146 = x92 = o444 = b10010010
  54. // 182 = xb6 = o555 = b10110110
  55. // 219 = xdb = o666 = b11011011
  56. // 255 = xff = o777 = b11111111
  57.  
  58. //   0 = x00 = b00000000
  59. //  17 = x11 = b00010001
  60. //  34 = x22 = b00100010
  61. //  51 = x33 = b00110011
  62. //  68 = x44 = b01000100
  63. //  85 = x55 = b01010101
  64. // 102 = x66 = b01100110
  65. // 119 = x77 = b01110111
  66. // 136 = x88 = b10001000
  67. // 153 = x99 = b10011001
  68. // 170 = xaa = b10101010
  69. // 187 = xbb = b10111011
  70. // 204 = xcc = b11001100
  71. // 221 = xdd = b11011101
  72. // 238 = xee = b11101110
  73. // 255 = xff = b11111111 
  74.  
  75. // 16 grey shade palette
  76. UBYTE BW16_Palette[48] = {
  77.     0,0,0,
  78.     17,17,17,
  79.     34,34,34,
  80.     51,51,51,
  81.     68,68,68,
  82.     85,85,85,
  83.     102,102,102,
  84.     119,119,119,
  85.     136,136,136,
  86.     153,153,153,
  87.     170,170,170,
  88.     187,187,187,
  89.     204,204,204,
  90.     221,221,221,
  91.     238,238,238,
  92.     255,255,255
  93. };
  94.  
  95. // 256 grey shade palette
  96. UBYTE BW256_Palette[768] = {
  97.     0,0,0,
  98.     1,1,1,
  99.     2,2,2,
  100.     3,3,3,
  101.     4,4,4,
  102.     5,5,5,
  103.     6,6,6,
  104.     7,7,7,
  105.     8,8,8,
  106.     9,9,9,
  107.     10,10,10,
  108.     11,11,11,
  109.     12,12,12,
  110.     13,13,13,
  111.     14,14,14,
  112.     15,15,15,
  113.     16,16,16,
  114.     17,17,17,
  115.     18,18,18,
  116.     19,19,19,
  117.     20,20,20,
  118.     21,21,21,
  119.     22,22,22,
  120.     23,23,23,
  121.     24,24,24,
  122.     25,25,25,
  123.     26,26,26,
  124.     27,27,27,
  125.     28,28,28,
  126.     29,29,29,
  127.     30,30,30,
  128.     31,31,31,
  129.     32,32,32,
  130.     33,33,33,
  131.     34,34,34,
  132.     35,35,35,
  133.     36,36,36,
  134.     37,37,37,
  135.     38,38,38,
  136.     39,39,39,
  137.     40,40,40,
  138.     41,41,41,
  139.     42,42,42,
  140.     43,43,43,
  141.     44,44,44,
  142.     45,45,45,
  143.     46,46,46,
  144.     47,47,47,
  145.     48,48,48,
  146.     49,49,49,
  147.     50,50,50,
  148.     51,51,51,
  149.     52,52,52,
  150.     53,53,53,
  151.     54,54,54,
  152.     55,55,55,
  153.     56,56,56,
  154.     57,57,57,
  155.     58,58,58,
  156.     59,59,59,
  157.     60,60,60,
  158.     61,61,61,
  159.     62,62,62,
  160.     63,63,63,
  161.     64,64,64,
  162.     65,65,65,
  163.     66,66,66,
  164.     67,67,67,
  165.     68,68,68,
  166.     69,69,69,
  167.     70,70,70,
  168.     71,71,71,
  169.     72,72,72,
  170.     73,73,73,
  171.     74,74,74,
  172.     75,75,75,
  173.     76,76,76,
  174.     77,77,77,
  175.     78,78,78,
  176.     79,79,79,
  177.     80,80,80,
  178.     81,81,81,
  179.     82,82,82,
  180.     83,83,83,
  181.     84,84,84,
  182.     85,85,85,
  183.     86,86,86,
  184.     87,87,87,
  185.     88,88,88,
  186.     89,89,89,
  187.     90,90,90,
  188.     91,91,91,
  189.     92,92,92,
  190.     93,93,93,
  191.     94,94,94,
  192.     95,95,95,
  193.     96,96,96,
  194.     97,97,97,
  195.     98,98,98,
  196.     99,99,99,
  197.     100,100,100,
  198.     101,101,101,
  199.     102,102,102,
  200.     103,103,103,
  201.     104,104,104,
  202.     105,105,105,
  203.     106,106,106,
  204.     107,107,107,
  205.     108,108,108,
  206.     109,109,109,
  207.     110,110,110,
  208.     111,111,111,
  209.     112,112,112,
  210.     113,113,113,
  211.     114,114,114,
  212.     115,115,115,
  213.     116,116,116,
  214.     117,117,117,
  215.     118,118,118,
  216.     119,119,119,
  217.     120,120,120,
  218.     121,121,121,
  219.     122,122,122,
  220.     123,123,123,
  221.     124,124,124,
  222.     125,125,125,
  223.     126,126,126,
  224.     127,127,127,
  225.     128,128,128,
  226.     129,129,129,
  227.     130,130,130,
  228.     131,131,131,
  229.     132,132,132,
  230.     133,133,133,
  231.     134,134,134,
  232.     135,135,135,
  233.     136,136,136,
  234.     137,137,137,
  235.     138,138,138,
  236.     139,139,139,
  237.     140,140,140,
  238.     141,141,141,
  239.     142,142,142,
  240.     143,143,143,
  241.     144,144,144,
  242.     145,145,145,
  243.     146,146,146,
  244.     147,147,147,
  245.     148,148,148,
  246.     149,149,149,
  247.     150,150,150,
  248.     151,151,151,
  249.     152,152,152,
  250.     153,153,153,
  251.     154,154,154,
  252.     155,155,155,
  253.     156,156,156,
  254.     157,157,157,
  255.     158,158,158,
  256.     159,159,159,
  257.     160,160,160,
  258.     161,161,161,
  259.     162,162,162,
  260.     163,163,163,
  261.     164,164,164,
  262.     165,165,165,
  263.     166,166,166,
  264.     167,167,167,
  265.     168,168,168,
  266.     169,169,169,
  267.     170,170,170,
  268.     171,171,171,
  269.     172,172,172,
  270.     173,173,173,
  271.     174,174,174,
  272.     175,175,175,
  273.     176,176,176,
  274.     177,177,177,
  275.     178,178,178,
  276.     179,179,179,
  277.     180,180,180,
  278.     181,181,181,
  279.     182,182,182,
  280.     183,183,183,
  281.     184,184,184,
  282.     185,185,185,
  283.     186,186,186,
  284.     187,187,187,
  285.     188,188,188,
  286.     189,189,189,
  287.     190,190,190,
  288.     191,191,191,
  289.     192,192,192,
  290.     193,193,193,
  291.     194,194,194,
  292.     195,195,195,
  293.     196,196,196,
  294.     197,197,197,
  295.     198,198,198,
  296.     199,199,199,
  297.     200,200,200,
  298.     201,201,201,
  299.     202,202,202,
  300.     203,203,203,
  301.     204,204,204,
  302.     205,205,205,
  303.     206,206,206,
  304.     207,207,207,
  305.     208,208,208,
  306.     209,209,209,
  307.     210,210,210,
  308.     211,211,211,
  309.     212,212,212,
  310.     213,213,213,
  311.     214,214,214,
  312.     215,215,215,
  313.     216,216,216,
  314.     217,217,217,
  315.     218,218,218,
  316.     219,219,219,
  317.     220,220,220,
  318.     221,221,221,
  319.     222,222,222,
  320.     223,223,223,
  321.     224,224,224,
  322.     225,225,225,
  323.     226,226,226,
  324.     227,227,227,
  325.     228,228,228,
  326.     229,229,229,
  327.     230,230,230,
  328.     231,231,231,
  329.     232,232,232,
  330.     233,233,233,
  331.     234,234,234,
  332.     235,235,235,
  333.     236,236,236,
  334.     237,237,237,
  335.     238,238,238,
  336.     239,239,239,
  337.     240,240,240,
  338.     241,241,241,
  339.     242,242,242,
  340.     243,243,243,
  341.     244,244,244,
  342.     245,245,245,
  343.     246,246,246,
  344.     247,247,247,
  345.     248,248,248,
  346.     249,249,249,
  347.     250,250,250,
  348.     251,251,251,
  349.     252,252,252,
  350.     253,253,253,
  351.     254,254,254,
  352.     255,255,255,
  353. };
  354.  
  355. // HAM6 base palette
  356. // note 3 extra entries based on changing r,g or b using HAM stuff
  357. UBYTE HAM6_Palette[57] = {
  358.     0,0,0,
  359.     0,0,170,
  360.     0,85,0,
  361.     0,85,170,
  362.     0,170,0,
  363.     0,170,170,
  364.     0,255,0,
  365.     0,255,170,
  366.     170,0,0,
  367.     170,0,170,
  368.     170,85,0,
  369.     170,85,170,
  370.     170,170,0,
  371.     170,170,170,
  372.     170,255,0,
  373.     170,255,170,
  374.     0,0,0,    // r
  375.     0,0,0,    // g
  376.     0,0,0,    // b
  377. };
  378.  
  379. // HAM8 base palette
  380. // note 3 extra entries based on changing r,g or b using HAM stuff
  381. UBYTE HAM8_Palette[201] = {
  382.     0,0,0,
  383.     0,0,170,
  384.     0,36,0,
  385.     0,36,170,
  386.     0,73,0,
  387.     0,73,170,
  388.     0,109,0,
  389.     0,109,170,
  390.     0,146,0,
  391.     0,146,170,
  392.     0,182,0,
  393.     0,182,170,
  394.     0,219,0,
  395.     0,219,170,
  396.     0,255,0,
  397.     0,255,170,
  398.     85,0,0,
  399.     85,0,170,
  400.     85,36,0,
  401.     85,36,170,
  402.     85,73,0,
  403.     85,73,170,
  404.     85,109,0,
  405.     85,109,170,
  406.     85,146,0,
  407.     85,146,170,
  408.     85,182,0,
  409.     85,182,170,
  410.     85,219,0,
  411.     85,219,170,
  412.     85,255,0,
  413.     85,255,170,
  414.     170,0,0,
  415.     170,0,170,
  416.     170,36,0,
  417.     170,36,170,
  418.     170,73,0,
  419.     170,73,170,
  420.     170,109,0,
  421.     170,109,170,
  422.     170,146,0,
  423.     170,146,170,
  424.     170,182,0,
  425.     170,182,170,
  426.     170,219,0,
  427.     170,219,170,
  428.     170,255,0,
  429.     170,255,170,
  430.     255,0,0,
  431.     255,0,170,
  432.     255,36,0,
  433.     255,36,170,
  434.     255,73,0,
  435.     255,73,170,
  436.     255,109,0,
  437.     255,109,170,
  438.     255,146,0,
  439.     255,146,170,
  440.     255,182,0,
  441.     255,182,170,
  442.     255,219,0,
  443.     255,219,170,
  444.     255,255,0,
  445.     255,255,170,
  446.     0,0,0,    // r
  447.     0,0,0,    // g
  448.     0,0,0,    // b
  449. };
  450.  
  451. /* save 16 grey scale
  452.  * FileName : file to save
  453.  * width    : width of image
  454.  * height   : height of image
  455.  * swidth   : widht of image when in full words
  456.  * pwidth   : page width
  457.  * pheight  : page height
  458.  * pmode    : camg chunk
  459.  * red      : red
  460.  * green    : green
  461.  * blue     : blue chunky bit map
  462.  * rp       : a work rast port
  463.  * trp      : another work rast port
  464.  */
  465. BOOL
  466. SaveBW16(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  467.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  468.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp) {
  469.     UBYTE *r,*g,*b,*old;
  470.     UWORD x,y;
  471.     BOOL OkFlag;
  472.     struct ILBMInfo *ilbm;
  473.     // allocate IFF stuff
  474.     if (ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
  475.         if (ilbm->ParseInfo.iff = AllocIFF()) {
  476.             r = red;
  477.             g = green;
  478.             b = blue;
  479.             old = red;
  480.             // for each line
  481.             for (y=0;
  482.                   y<height;
  483.                   y++) {
  484.                 // for each column
  485.                 for (x=0;
  486.                       x < width;
  487.                       x++) {
  488.                     // convert rgb to 16 grey scale
  489.                     *old++ = ((30 * *r++) + (59 * *g++) + (11 * *b++)) / 1594;
  490.                 }
  491.                 r += (swidth - width);
  492.                 g += (swidth - width);
  493.                 b += (swidth - width);
  494.                 old += (swidth - width);
  495.             }
  496.             // convert chunky to planar
  497.             WritePixelArray8(rp,0,0,width-1,height-1,red,trp);
  498.             // and save IFF
  499.             OkFlag = !saveilbm(ilbm, rp->BitMap, pmode,
  500.                                      width,  height, pwidth, pheight,
  501.                                      BW16_Palette, 16, 8,    /* colortable */
  502.                                      mskNone, 0,    /* masking, transparent */
  503.                                      NULL, NULL,     /* chunklists */
  504.                                      FileName);
  505.             // Close everything down cleanly
  506.             FreeIFF(ilbm->ParseInfo.iff);
  507.         }
  508.         else {
  509.             OkFlag = FALSE;
  510.         }
  511.         FreeMem(ilbm,sizeof(struct ILBMInfo));
  512.     }
  513.     else {
  514.         OkFlag = FALSE;
  515.     }
  516.     return OkFlag;
  517. }
  518.  
  519. /* save 256 grey scale
  520.  * see SaveBW16()
  521.  */
  522. BOOL
  523. SaveBW256(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  524.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  525.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp) {
  526.     UBYTE *r,*g,*b,*old;
  527.     UWORD x,y;
  528.     BOOL OkFlag;
  529.     struct ILBMInfo *ilbm;
  530.     if (ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
  531.         if (ilbm->ParseInfo.iff = AllocIFF()) {
  532.             r = red;
  533.             g = green;
  534.             b = blue;
  535.             old = red;
  536.             for (y=0;
  537.                   y<height;
  538.                   y++) {
  539.                 for (x=0;
  540.                       x < width;
  541.                       x++) {
  542.                     // convert rgb to 256 grey scale
  543.                     *old = ((30 * *r++) + (59 * *g++) + (11 * *b++)) / 100;
  544.                 }
  545.                 r += (swidth - width);
  546.                 g += (swidth - width);
  547.                 b += (swidth - width);
  548.                 old += (swidth - width);
  549.             }
  550.             WritePixelArray8(rp,0,0,width-1,height-1,red,trp);
  551.             OkFlag = !saveilbm(ilbm, rp->BitMap, pmode,
  552.                                      width,  height, pwidth, pheight,
  553.                                      BW256_Palette, 256, 8,    /* colortable */
  554.                                      mskNone, 0,    /* masking, transparent */
  555.                                      NULL, NULL,     /* chunklists */
  556.                                      FileName);
  557.             // Close everything down cleanly
  558.             FreeIFF(ilbm->ParseInfo.iff);
  559.         }
  560.         else {
  561.             OkFlag = FALSE;
  562.         }
  563.         FreeMem(ilbm,sizeof(struct ILBMInfo));
  564.     }
  565.     else {
  566.         OkFlag = FALSE;
  567.     }
  568.     return OkFlag;
  569. }
  570.  
  571. /* save HAM6
  572.  * see SaveBW16()
  573.  */
  574. BOOL
  575. SaveHAM6(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  576.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  577.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp) {
  578.     UBYTE *r,*g,*b,*old,*p;
  579.     UWORD x,y;
  580.     ULONG maxdiff;
  581.     ULONG diff;
  582.     LONG t;
  583.     UWORD k;
  584.     UWORD index;
  585.     BOOL OkFlag;
  586.     struct ILBMInfo *ilbm;
  587.     UBYTE lr,lg,lb;
  588.     if (ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
  589.         if (ilbm->ParseInfo.iff = AllocIFF()) {
  590.             r = red;
  591.             g = green;
  592.             b = blue;
  593.             old = red;
  594.             for (y=0;
  595.                   y<height;
  596.                   y++) {
  597.                 lr = 0;
  598.                 lg = 0;
  599.                 lb = 0;
  600.                 for (x=0;
  601.                       x < width;
  602.                       x++) {
  603.                     // colour if we use HAM to change R or G or B
  604.                     HAM6_Palette[16*3] = *r;
  605.                     HAM6_Palette[16*3+1] = lg;
  606.                     HAM6_Palette[16*3+2] = lb;
  607.                     HAM6_Palette[17*3] = lr;
  608.                     HAM6_Palette[17*3+1] = *g;
  609.                     HAM6_Palette[17*3+2] = lb;
  610.                     HAM6_Palette[18*3] = lr;
  611.                     HAM6_Palette[18*3+1] = lg;
  612.                     HAM6_Palette[18*3+2] = *b;
  613.                     // Find closest color
  614.                     maxdiff = 0x7FFFFFFF;
  615.                     p = HAM6_Palette;
  616.                     for (k = 0;
  617.                           k < 19;
  618.                           ++k) {
  619.                         t = *r - *p++;
  620.                         diff = t*t*3;
  621.                         t = *g - *p++;
  622.                         diff += (t*t*6);
  623.                         t = *b - *p++;
  624.                         diff += (t*t);
  625.                         if (diff < maxdiff) {
  626.                             maxdiff = diff;
  627.                             index = k;
  628.                         }
  629.                     }
  630.                     lr = HAM6_Palette[index*3];
  631.                     lg = HAM6_Palette[index*3+1];
  632.                     lb = HAM6_Palette[index*3+2];
  633.                     // Set HAM bits if required
  634.                     if (index == 16) {
  635.                         *old++ = (*r>>4) | 0x20;
  636.                     }
  637.                     else {
  638.                         if (index == 17) {
  639.                             *old++ = (*g>>4) | 0x30;
  640.                         }
  641.                         else {
  642.                             if (index == 18) {
  643.                                 *old++ = (*b>>4) | 0x10;
  644.                             }
  645.                             else {
  646.                                 *old++ = index;
  647.                             }
  648.                         }
  649.                     }
  650.                     r++;
  651.                     g++;
  652.                     b++;
  653.                 }
  654.                 r += (swidth - width);
  655.                 g += (swidth - width);
  656.                 b += (swidth - width);
  657.                 old += (swidth - width);
  658.             }
  659.             WritePixelArray8(rp,0,0,width-1,height-1,red,trp);
  660.             OkFlag = !saveilbm(ilbm, rp->BitMap, pmode | HAM,
  661.                                      width,  height, pwidth, pheight,
  662.                                      HAM6_Palette, 16, 8,    /* colortable */
  663.                                      mskNone, 0,    /* masking, transparent */
  664.                                      NULL, NULL,     /* chunklists */
  665.                                      FileName);
  666.             // Close everything down cleanly
  667.             FreeIFF(ilbm->ParseInfo.iff);
  668.         }
  669.         else {
  670.             OkFlag = FALSE;
  671.         }
  672.         FreeMem(ilbm,sizeof(struct ILBMInfo));
  673.     }
  674.     else {
  675.         OkFlag = FALSE;
  676.     }
  677.     return OkFlag;
  678. }
  679.  
  680. /* save HAM8
  681.  * see SaveHAM6()
  682.  */
  683. BOOL SaveHAM8(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  684.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  685.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp) {
  686.     UBYTE *r,*g,*b,*old,*p;
  687.     UWORD x,y;
  688.     ULONG maxdiff;
  689.     ULONG diff;
  690.     LONG t;
  691.     UWORD k;
  692.     UWORD index;
  693.     BOOL OkFlag;
  694.     struct ILBMInfo *ilbm;
  695.     UBYTE lr,lg,lb;
  696.     if (ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
  697.         if (ilbm->ParseInfo.iff = AllocIFF()) {
  698.             r = red;
  699.             g = green;
  700.             b = blue;
  701.             old = red;
  702.             for (y=0;
  703.                   y<height;
  704.                   y++) {
  705.                 lr = 0;
  706.                 lg = 0;
  707.                 lb = 0;
  708.                 for (x=0;
  709.                       x < width;
  710.                       x++) {
  711.                     HAM8_Palette[64*3] = *r;
  712.                     HAM8_Palette[64*3+1] = lg;
  713.                     HAM8_Palette[64*3+2] = lb;
  714.                     HAM8_Palette[65*3] = lr;
  715.                     HAM8_Palette[65*3+1] = *g;
  716.                     HAM8_Palette[65*3+2] = lb;
  717.                     HAM8_Palette[66*3] = lr;
  718.                     HAM8_Palette[66*3+1] = lg;
  719.                     HAM8_Palette[66*3+2] = *b;
  720.                     // Find closest color
  721.                     maxdiff = 0x7FFFFFFF;
  722.                     p = HAM8_Palette;
  723.                     for (k = 0;
  724.                           k < 67;
  725.                           ++k) {
  726.                         t = *r - *p++;
  727.                         diff = t*t*3;
  728.                         t = *g - *p++;
  729.                         diff += (t*t*6);
  730.                         t = *b - *p++;;
  731.                         diff += (t*t);
  732.                         if (diff < maxdiff) {
  733.                             maxdiff = diff;
  734.                             index = k;
  735.                         }
  736.                     }
  737.                     lr = HAM8_Palette[index*3];
  738.                     lg = HAM8_Palette[index*3+1];
  739.                     lb = HAM8_Palette[index*3+2];
  740.                     if (index == 64) {
  741.                         *old++ = (*r>>2) | 0x80;
  742.                     }
  743.                     else {
  744.                         if (index == 65) {
  745.                             *old++ = (*g>>2) | 0xc0;
  746.                         }
  747.                         else {
  748.                             if (index == 66) {
  749.                                 *old++ = (*b>>2) | 0x40;
  750.                             }
  751.                             else {
  752.                                 *old++ = index;
  753.                             }
  754.                         }
  755.                     }
  756.                     r++;
  757.                     g++;
  758.                     b++;
  759.                 }
  760.                 r += (swidth - width);
  761.                 g += (swidth - width);
  762.                 b += (swidth - width);
  763.                 old += (swidth - width);
  764.             }
  765.             WritePixelArray8(rp,0,0,width-1,height-1,red,trp);
  766.             OkFlag = !saveilbm(ilbm, rp->BitMap, pmode | HAM,
  767.                                      width,  height, pwidth, pheight,
  768.                                      HAM8_Palette, 64, 8,    /* colortable */
  769.                                      mskNone, 0,    /* masking, transparent */
  770.                                      NULL, NULL,     /* chunklists */
  771.                                      FileName);
  772.             // Close everything down cleanly
  773.             FreeIFF(ilbm->ParseInfo.iff);
  774.         }
  775.         else {
  776.             OkFlag = FALSE;
  777.         }
  778.         FreeMem(ilbm,sizeof(struct ILBMInfo));
  779.     }
  780.     else {
  781.         OkFlag = FALSE;
  782.     }
  783.     return OkFlag;
  784. }
  785.  
  786. /* save DCTV
  787.  * see SaveBW16()
  788.  */
  789. BOOL SaveDCTV(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  790.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  791.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp) {
  792.     UWORD i;
  793.     BOOL OkFlag;
  794.     struct ILBMInfo *ilbm;
  795.     struct DCTVCvtHandle *chandle;
  796.  
  797.     if (ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
  798.         if (ilbm->ParseInfo.iff = AllocIFF()) {
  799.             // Allocate DCTV stuff
  800.             if (chandle = AllocDCTVCvtTags(rp->BitMap,
  801.                                             DCTVCVTA_Type, DCTVCVTT_RGBtoDCTV,
  802.                                             DCTVCVTA_Flags,((pmode|LACE)?DCTVCVTF_Lace:0)|
  803.                                                                 DCTVCVTF_Filter|
  804.                                                                 DCTVCVTF_CustomRGBBuf,
  805.                                             TAG_END)) {
  806.                 chandle->Red = red;
  807.                 chandle->Green = green;
  808.                 chandle->Blue = blue;
  809.                 // Convert each line
  810.                 while (chandle->DstLineNum < chandle->Height) {
  811.                     i = chandle->SrcLineNum;
  812.                     CvtDCTVLine(chandle);
  813.                     if (i != chandle->SrcLineNum) {
  814.                         chandle->Red += swidth;
  815.                         chandle->Green += swidth;
  816.                         chandle->Blue += swidth;
  817.                     }
  818.                 }
  819.                 OkFlag = !saveilbm(ilbm, rp->BitMap, pmode,
  820.                                      width,  height, pwidth, pheight,
  821.                                      chandle->ColorTable, 1L << rp->BitMap->Depth, 4,    /* colortable */
  822.                                      mskNone, 0,    /* masking, transparent */
  823.                                      NULL, NULL,     /* chunklists */
  824.                                      FileName);
  825.                 // Free DCTV stuff
  826.                 FreeDCTVCvt(chandle);
  827.             }
  828.             else {
  829.                 OkFlag = FALSE;
  830.             }
  831.             // Close everything down cleanly
  832.             FreeIFF(ilbm->ParseInfo.iff);
  833.         }
  834.         else {
  835.             OkFlag = FALSE;
  836.         }
  837.         FreeMem(ilbm,sizeof(struct ILBMInfo));
  838.     }
  839.     else {
  840.         OkFlag = FALSE;
  841.     }
  842.     return OkFlag;
  843. }
  844.